/**
 * 函数
 */

//  1、事件
//  <input type="button" value="点我啊！" id="sub">
//  <script>
//      //获得按钮元素
//      var sub=document.querySelector("#sub");
//      //给按钮增加点击事件。
//      sub.onclick=function(){
//          alert("当点击按钮时会执行到我哦！");
//      }
//  </script>

// 2、对象
var obj = {
    name: "张培跃",
    age: 18,
    fn: function () {
        return "我叫" + this.name + "今年" + this.age + "岁了！";
    }
};
console.log(obj.fn());//我叫张培跃今年18岁了！

// 3、函数表达式
//将匿名函数赋值给变量fn。
var fn = function () {
    return "我是一只小小小小留下，怎么飞也飞不高！"
}
// 调用方式与调用普通函数一样
console.log(fn());//我是一只小小小小留下，怎么飞也飞不高！

// 4、回调函数
// setInterval(function () {
//     console.log("我其实是一个回调函数，每次1秒钟会被执行一次");
// }, 1000);

// 5、返回值
// 将匿名函数作为返回值
function fn() {
    // 返回匿名函数
    return function () {
        return "张培跃";
    }
}

// 调用匿名函数
// console.log(fn()());// 张培跃
// 或
var box = fn();
// console.log(box());// 张培跃


// 模仿块级作用域
// 块级作用域，有的地方称为私有作用域。JavaScript中是没有块级作用域的，例如
if (1 == 1) {//条件成立，执行if代码块语句。
    var a = 12;//a为全局变量
}
console.log(a); // 12

for (var i = 0; i < 3; i++) {
    console.log(i);
}
console.log(i);// 0 1 2 3

//  尝试块级作用域
function fn() {
    (function () {
        var la = "啦啦啦！";
    })();
    console.log(la);// 报错---la is not defined
}

fn();

// 递归求斐波那契
function fbnq(n) {
    if (n < 2) {
        return n;
    }
    return fbnq(n-1) + fbnq(n-2);
}
console.log("fbnq:", fbnq(3))

// 代理模式
const hd = {name: "hd"}
const proxy = new Proxy(hd, {
    get (obj, property) {
        return obj[property];
    },
    set (obj, property, value) {
        obj[property] = value;
        return true;
    }
})
console.log(proxy.name);
proxy.name = '哇哈哈';
console.log(proxy.name);


//  匿名函数的作用
//  1、 
//      通过匿名函数可以实现闭包，关于闭包在后面的文章中会重点讲解。在这里简单介绍一下
//      闭包是可以访问在函数作用域内定义的变量的函数。若要创建一个闭包，往往都需要用到匿名函数
//  2、
//      节省内存：模拟块级作用域，减少全局变量；执行完匿名函数，存储在内存中相对应的变量会被销毁，从而节省内存
//      划分临时作用域：在大型多人开发的项目中，使用块级作用域，会大大降低命名冲突的问题，从而避免产生灾难性的后果，自此开发者再也不必担心搞乱全局作用域
